﻿namespace StockSharp.Algo.Indicators.Trend
{
	using System;
	using System.ComponentModel;
	using System.Linq;

	/// <summary>
	/// Стандартное отклонение.
	/// </summary>
	[DisplayName("StdDev")]
	[Description("Стандартное отклонение.")]
	public class StandardDeviation : LengthIndicator<decimal>
	{
		private readonly SimpleMovingAverage _sma;

		/// <summary>
		/// Создать <see cref="StandardDeviation"/>.
		/// </summary>
		public StandardDeviation()
			: base(typeof(decimal))
		{
			_sma = new SimpleMovingAverage();
		}

		/// <summary>
		/// Длина периода.
		/// </summary>
		public override int Length
		{
			get
			{
				return _sma.Length;
			}
			set
			{
				_sma.Length = value;
				Reset();
			}
		}

		/// <summary>
		/// Сформирован ли индикатор.
		/// </summary>
		public override bool IsFormed { get { return _sma.IsFormed; } }

		/// <summary>
		/// Обработать входное значение.
		/// </summary>
		/// <param name="input">Входное значение.</param>
		/// <returns>Результирующее значение.</returns>
		protected override decimal OnProcess(IIndicatorValue input)
		{
			var smaValue = _sma.Process(input).GetValue<decimal>();

			Buffer.Add(input.GetValue<decimal>());

			//считаем значение отклонения в последней точке
			var std = Buffer.Select(t1 => t1 - smaValue).Select(t => t * t).Sum();

			if (IsFormed)
				Buffer.RemoveAt(0);

			return (decimal)Math.Sqrt((double)(std / Length));

		}
	}
}